package com.ydj.framework.third.tencentsms;

import com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.ydj.framework.exception.CommonException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * 腾讯发送短信
 */
@Slf4j
@Component
public class TencentSmsManager {

    // 短信应用SDK AppID
    @Value("${tencent.sms.appId}")
    private Integer APP_ID;

    // 短信应用SDK AppKey
    @Value("${tencent.sms.appKey}")
    private String APP_KEY;

    // 签名
    @Value("${tencent.sms.sign}")
    private String SMS_SIGN;

    // 短信模板ID
    private final int LOGIN_VERIFY_CODE_TEMPLATE_ID = 2508476;

    /**
     * 发送验证码给自己
     * @return 返回验证码
     */
    public void sendLoginVerifyCode(String phoneNumber, String verifyCode, int validityPeriod) throws CommonException {
        String[] params = {verifyCode, String.valueOf(validityPeriod)};
        sendSingle(LOGIN_VERIFY_CODE_TEMPLATE_ID, phoneNumber, params);
    }

    /**
     * 发送一条短信
     *
     * @param templateId  模板ID
     * @param phoneNumber 电话号码
     */
    private void sendSingle(int templateId, String phoneNumber, String[] params) throws CommonException {
        SmsSingleSenderResult result;
        try {
            //数组具体的元素个数和模板中变量个数必须一致，例如事例中templateId:5678对应一个变量，参数数组中元素个数也必须是一个
            SmsSingleSender sender = new SmsSingleSender(APP_ID, APP_KEY);
            // 签名参数未提供或者为空时，会使用默认签名发送短信
            result = sender.sendWithParam("86", phoneNumber, templateId, params, SMS_SIGN, "", "");
        } catch (Throwable e) {
            e.printStackTrace();
            log.error("发送短信给" + phoneNumber + "。", e);
            throw new CommonException("发送短信失败。");
        }

        // 检测腾讯返回的结果
        String resultCodeString = parseResultCodeToString(result.result);
        if (result.result == 0) {
            // 正常
            log.info("发送短信给{}, 模板{}, 结果正常。result={}", phoneNumber, templateId, result);
        } else {
            log.error("发送短信给{}, 模板{}, 结果错误{}，result={}", phoneNumber, templateId, resultCodeString, result);
            // 不为0，就是有问题，抛错误出去
            switch (result.result) {
                case 1013:
                case 1016:
                case 1022:
                case 1023:
                case 1024:
                case 1025:
                case 1026:
                case 1029:
                case 1038:
                case 1045:
                    throw new CommonException(resultCodeString);
                default:
                    break;
            }
        }
    }

    private static String parseResultCodeToString(int resultCode) {
        switch (resultCode) {
            case 1001:
                return "sig 校验失败";
            case 1002:
                return "短信/语音内容中含有敏感词";
            case 1003:
                return "请求包体没有 sig 字段或 sig 为空";
            case 1004:
                return "请求包解析失败，通常情况下是由于没有遵守 API 接口说明规范导致的";
            case 1006:
                return "请求没有权限";
            case 1007:
                return "其他错误";
            case 1008:
                return "请求下发短信/语音超时";
            case 1009:
                return "请求 IP 不在白名单中";
            case 1011:
                return "不存在该 REST API 接口";
            case 1012:
                return "签名格式错误或者签名未审批";
            case 1013:
                return "下发短信/语音命中了频率限制策略";
            case 1014:
                return "模版未审批或请求的内容与审核通过的模版内容不匹配";
            case 1015:
                return "手机号在黑名单库中，通常是用户退订或者命中运营商黑名单导致的";
            case 1016:
                return "手机号格式错误";
            case 1017:
                return "请求的短信内容太长";
            case 1018:
                return "语音验证码格式错误";
            case 1019:
                return "sdkappid 不存在";
            case 1020:
                return "sdkappid 已禁用";
            case 1021:
                return "请求发起时间不正常，通常是由于您的服务器时间与腾讯云服务器时间差异超过10分钟导致的";
            case 1022:
                return "业务短信日下发条数超过设定的上限";
            case 1023:
                return "单个手机号30秒内下发短信条数超过设定的上限";
            case 1024:
                return "单个手机号1小时内下发短信条数超过设定的上限";
            case 1025:
                return "单个手机号日下发短信条数超过设定的上限";
            case 1026:
                return "单个手机号下发相同内容超过设定的上限";
            case 1029:
                return "营销短信发送时间限制";
            case 1030:
                return "不支持该请求";
            case 1031:
                return "套餐包余量不足";
            case 1032:
                return "个人用户没有发营销短信的权限";
            case 1033:
                return "欠费被停止服务";
            case 1034:
                return "群发请求里既有国内手机号也有国际手机号";
            case 1036:
                return "单个模板变量字符数超过12个";
            case 1045:
                return "不支持该地区短信下发";
            case 1046:
                return "调用群发 API 接口单次提交的手机号个数超过200个";
            default:
                return "";
        }

    }
}
